#include <iostream>
#include <string.h>

using namespace std;

typedef int DataType;

class Vector{
	public:
		///////////////////////////////////////////////////////////////////
		//Constructor
		Vector()
			: _arr(new DataType[3])
			, _size(0)
			, _capacity(3)
		{
			cout << "调用普通构造函数" << endl;
		}

		Vector(DataType* left, DataType* right)
		{
			cout << "调用左闭右开区间 [left, right) 构造函数" << endl;
			size_t size = right - left;
			_arr = new DataType[size];
			_size = size;
			_capacity = size;

			for(size_t i = 0; i < size; ++i)
				_arr[i] = left[i];
		}

		Vector(size_t n, const DataType& data = DataType())
			: _arr(new DataType[n])
			, _size(n)
			, _capacity(n)
		{
			cout << "调用 n 个 data 的构造函数" << endl;
			for(size_t i = 0; i < n; ++i)
				_arr[i] = data;
		}

		Vector(const Vector& v)
		{
			// 调用拷贝构造函数
			_arr = new DataType[v._capacity];
			memset(_arr, 0, v._capacity*sizeof(DataType));

			for(size_t i = 0; i < v._size; ++i)
				_arr[i] = v._arr[i];

			_size = v._size;
			_capacity = v._capacity;
		}
		
		///////////////////////////////////////////////////////////
		//Access
		DataType& operator[](size_t pos)
		{
			if(pos < Size())
				return _arr[pos];
		}

		const DataType& operator[](size_t pos)const
		{
			if(pos < _size)
				return _arr[pos];
		}

		DataType& Front()
		{
			return _arr[0];
		}

		const DataType& Front()const
		{
			return _arr[0];
		}

		DataType& Back()
		{	
			return _arr[_size - 1];
		}

		const DataType& Back()const
		{	
			return _arr[_size - 1];
		}

		///////////////////////////////////////////////////////////
		//Capacity
		size_t Size()
		{
			return _size;
		}

		size_t Capacity()
		{
			return _capacity;
		}

		// 重新设置有效元素数量，多出来的用data填充
		void ReSize(size_t newSize, const DataType& data = DataType())
		{
			size_t oldSize = Size();
			if(newSize < oldSize) {
				_size = newSize;
			}
			else {
				if(newSize < Capacity()) {
					for(size_t i = oldSize; i < newSize; ++i) {
						_arr[i] = data;
					}
					_size = newSize;
				}
				else {
					DataType* pTemp = new DataType[newSize];
					for(size_t i = 0; i < oldSize; ++i)
						pTemp[i] = _arr[i];
					for(size_t i = oldSize; i < newSize; ++i)
						pTemp[i] = data;

					delete[] _arr;
					_arr = pTemp;
					_size = newSize;
					_capacity = newSize;
				}
			}
		}

		// 为当前动态顺序表预留空间，不改变有效元素的个数
		void Reverse(size_t newCapacity)
		{
			size_t oldCapacity = _capacity;
			if(oldCapacity < newCapacity)
			{
				DataType* temp = new DataType[newCapacity];
				memset(temp, 0, newCapacity * sizeof(DataType));
				for(size_t i = 0 ; i < _size; ++i)
				{
					temp[i] = _arr[i];
				}

				delete[] _arr;
				_arr = temp;
				_capacity = newCapacity;
			}
		}

		void CheckCapacity()
		{
			if(_size == _capacity)
				Reverse(_capacity * 2);
		}

		//////////////////////////////////////////////////////
		// Modify
		void PushBack(const DataType& data)
		{
			CheckCapacity();
			_arr[_size++] = data;
		}

		void PopBack()
		{
			_size--;
		}

		// 插入到pos前面
		void Insert(size_t pos, const DataType& data)
		{
			if(pos < _size)
			{
				for(size_t i = _size; i > pos; --i) {
					_arr[i] = _arr[i - 1];
				}
				_arr[pos] = data;
				++_size;
			}
		}

		void Erase(size_t pos)
		{
			if(pos < _size)
			{
				for(size_t i = pos; i < _size; ++i)
				{
					_arr[i] = _arr[i + 1];
				}
				--_size;
			}
		}

		void Clear()
		{
			_size = 0;
		}
	friend ostream& operator<<(ostream& _cout, const Vector& v);
	private:
		DataType* _arr;
		size_t _size;
		size_t _capacity;
};

ostream& operator<<(ostream& _cout, const Vector& v)
{
	cout << "Array: ";
	for(size_t i = 0; i < v._size; ++i)
		_cout << v._arr[i] << " ";
	_cout << endl;
	_cout << "Size: " << v._size << endl;
	_cout << "Capacity: " << v._capacity << endl;
	return _cout;
}

int main()
{
	Vector v1;
	cout << v1 << endl;

	v1.PushBack(1);
	v1.PushBack(2);
	v1.PushBack(3);
	v1.PushBack(4);
	v1.PushBack(5);
	v1.PushBack(6);
	v1.PushBack(7);
	cout << v1 << endl;

	cout << v1.Size() << endl;
	cout << v1.Capacity() << endl;

	v1.PopBack();
	v1.PopBack();
	v1.PopBack();
	cout << v1 << endl;

	cout << v1.Front() << endl;
	cout << v1.Back() << endl;

	Vector v2(5, 6);
	cout << v2 << endl;
	v2.PushBack(7);
	cout << v2 << endl;

	v2.ReSize(3);
	cout << v2 << endl;

	v2.ReSize(10);
	cout << v2 << endl;

	Vector v3(v1);
	cout << v3 << endl;

	return 0;
}
